﻿/*   
    Copyright (C) 2009 Galaktika Corporation ZAO

    This file is a part of Galaktika.BusinessMonitor
 
    Galaktika.BusinessMonitor is a free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
      
    You should have received a copy of the GNU General Public License
    along with Galaktika.BusinessMonitor.  If not, see <http://www.gnu.org/licenses/>.
  
    If GPL v.3 is not suitable for your products or company,
    Galaktika Corp provides Galaktika.BusinessMonitor under a flexible commercial license
    designed to meet your specific usage and distribution requirements.
    If you have already obtained a commercial license from Galaktika Corp,
    you can use this file under those license terms.
*/

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Net;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Galaktika.BI.Runtime.Services;
using System.Security;
using System.ComponentModel;
using System.Windows.Browser;
using Ranet.AgOlap.Controls.ContextMenu;
using System.Text;
using System.Windows.Markup;
using Galaktika.BI.Silverlight.Controls;

namespace Galaktika.BI.Silverlight.ClientApp.Items
{
    public class UserTaskPanel : ContentControl
    {
        internal static int MaxUserItemsCount = 50;
        #region TaskCache
        internal class TaskCache
        {
            ObservableCollection<TaskContainer> m_Tasks = new ObservableCollection<TaskContainer>();
            DataGrid m_Panel;
            public TaskCache(DataGrid panel)
            {
                m_Panel = panel;
                m_Panel.ItemsSource = m_Tasks;
                //for (int i = 0; i < MAX_ITEMS; i++)
                //{
                //    panel.RowDefinitions.Add(new RowDefinition() { Height = GridLength.Auto });
                //}
            }

            private bool m_ShowAll = true;
            public void SetFilter(bool showAll)
            {
                m_ShowAll = showAll;
                this.RefreshDataSource();
            }

            public void Append(UserTaskDescriptor task)
            {
                if (m_Tasks.Count == MaxUserItemsCount)
                {
                    //this.Remove(m_Tasks[1]);
                    m_Tasks.RemoveAt(MaxUserItemsCount - 1);
                }
                TaskContainer container = new TaskContainer(task, this);
                m_Tasks.Insert(0, container);
                this.Add(container);

                this.RefreshAll();

            }

            public void ClearAll()
            {
                m_Tasks.Clear();
            }

            public void RefreshDataSource()
            {
                if (m_ShowAll)
                {
                    m_Panel.ItemsSource = m_Tasks;
                }
                else
                {
                    m_Panel.ItemsSource = m_Tasks.Where<TaskContainer>(task => string.IsNullOrEmpty(task.Finished));
                }
            }

            public void RefreshAll()
            {
                this.RefreshDataSource();
                m_Panel.BeginEdit();
                for (int i = 0; i < m_Tasks.Count; i++)
                {
                    m_Tasks[i].SetRow(m_Tasks.Count - i);
                    m_Tasks[i].Refresh();
                }
                //m_Panel.ItemsSource = null;
                m_Panel.CommitEdit(DataGridEditingUnit.Row, true);
            }

            private void Remove(TaskContainer container)
            {
                //m_Panel.Children.Remove(container.StateImage);
                //m_Panel.Children.Remove(container.Caption);
                //m_Panel.Children.Remove(container.Started);
                //m_Panel.Children.Remove(container.Finished);
                //m_Panel.Children.Remove(container.Executed);
                //m_Panel.Children.Remove(container.Description);
            }

            private void Add(TaskContainer container)
            {
                //m_Panel.Children.Add(container.StateImage);
                //m_Panel.Children.Add(container.Caption);
                //m_Panel.Children.Add(container.Started);
                //m_Panel.Children.Add(container.Finished);
                //m_Panel.Children.Add(container.Executed);
                //m_Panel.Children.Add(container.Description);
            }
        }
        #endregion
        #region TaskContainer
        [SecuritySafeCritical]
        public class TaskContainer : INotifyPropertyChanged
        {
            private TaskCache m_Cache;
            internal TaskContainer(UserTaskDescriptor task, TaskCache cache)
            {
                m_Task = task;
                m_Cache = cache;
                //this.StateImage = new Image() { Margin = new Thickness(5.0, 0.0, 5.0, 0.0) };
                //this.Caption = new TextBlock() { Margin = new Thickness(5.0, 0.0, 5.0, 0.0) };
                //this.Started = new TextBlock() { Margin = new Thickness(5.0, 0.0, 5.0, 0.0) };
                //this.Finished = new TextBlock() { Margin = new Thickness(5.0, 0.0, 5.0, 0.0) };
                //this.Executed = new TextBlock() { Margin = new Thickness(5.0, 0.0, 5.0, 0.0) };
                //this.Description = new TextBlock() { Margin = new Thickness(5.0, 0.0, 5.0, 0.0), TextAlignment = TextAlignment.Right };

                //Grid.SetColumn(this.StateImage, 0);
                //Grid.SetColumn(this.Caption, 1);
                //Grid.SetColumn(this.Started, 2);
                //Grid.SetColumn(this.Finished, 3);
                //Grid.SetColumn(this.Executed, 4);
                //Grid.SetColumn(this.Description, 5);

                this.Refresh();
            }

            string m_StateImage;
            [SecuritySafeCritical]
            public string StateImage
            {
                get
                {
                    return m_StateImage;
                }
                set
                {
                    if (m_StateImage != value)
                    {
                        m_StateImage = value;
                        this.OnPropertyChanged("StateImage");
                    }
                }
            }

            string m_Caption;
            [SecuritySafeCritical]
            public string Caption 
            {
                get
                {
                    return m_Caption;
                }
                set
                {
                    if (m_Caption != value)
                    {
                        m_Caption = value;
                        this.OnPropertyChanged("Caption");
                    }
                }
            }

            string m_Started;
            [SecuritySafeCritical]
            public string Started 
            {
                get
                {
                    return m_Started;
                }
                set
                {
                    if (m_Started != value)
                    {
                        m_Started = value;
                        this.OnPropertyChanged("Started");
                    }
                }
            }

            string m_Finished;
            [SecuritySafeCritical]
            public string Finished
            {
                get
                {
                    return m_Finished;
                }
                set
                {
                    if (m_Finished != value)
                    {
                        m_Finished = value;
                        this.OnPropertyChanged("Finished");
                    }
                }
            }

            string m_Executed;
            [SecuritySafeCritical]
            public string Executed
            {
                get
                {
                    return m_Executed;
                }
                set
                {
                    if (m_Executed != value)
                    {
                        m_Executed = value;
                        this.OnPropertyChanged("Executed");
                    }
                }
            }

            string m_Description;
            [SecuritySafeCritical]
            public string Description
            {
                get
                {
                    return m_Description;
                }
                set
                {
                    if (m_Description != value)
                    {
                        m_Description = value;
                        this.OnPropertyChanged("Description");
                    }
                }
            }


            string m_FormId;
            [SecuritySafeCritical]
            public string FormId
            {
                get
                {
                    return m_FormId;
                }
                set
                {
                    if (m_FormId != value)
                    {
                        m_FormId = value;
                        this.OnPropertyChanged("FormId");
                    }
                }
            }

            private UserTaskDescriptor m_Task;
            public UserTaskDescriptor GetTask()
            {
                return m_Task;
            }

            public void SetRow(int index)
            {
                //Grid.SetRow(this.StateImage, index);
                //Grid.SetRow(this.Caption, index);
                //Grid.SetRow(this.Started, index);
                //Grid.SetRow(this.Finished, index);
                //Grid.SetRow(this.Executed, index);
                //Grid.SetRow(this.Description, index);
            }

            public void Refresh()
            {
                switch (m_Task.CurrentState)
                {
                    case WorkItemState.Running:
                        this.StateImage = ClientResources.Images.RUNNING_16;
                        break;
                    case WorkItemState.Done:
                        m_Cache.RefreshDataSource();
                        this.Finished = m_Task.Finished.Value.ToLongTimeString();
                        this.Executed = (m_Task.Finished - m_Task.Started).ToString();
                        if (m_Task.Exception == null)
                        {
                            this.StateImage = ClientResources.Images.DONE_16;
                            this.Description = this.GetCuttedMessage(m_Task.FinishMessage);
                        }
                        else
                        {
                            this.StateImage = ClientResources.Images.ABORTED_16;
                            this.Description = this.GetCuttedMessage(m_Task.Exception.Message);
                            //ToolTipService.SetToolTip(this.Description, m_Task.Exception);
                        }
                        break;
                    default:
                        throw new NotSupportedException(
                            string.Format("WorkItemState '{0}' does not supported", m_Task.CurrentState));
                }
                this.FormId = m_Task.FormId;
                this.Caption = m_Task.Caption;
                this.Started = m_Task.Started.ToLongTimeString();
            }

            private string GetCuttedMessage(string message)
            {
                if (string.IsNullOrEmpty(message))
                {
                    return message;
                }

                if (message.Length > 40)
                {
                    message = message.Substring(0, 40) + "...";
                }

                return message;
            }

            #region INotifyPropertyChanged Members

            public event PropertyChangedEventHandler PropertyChanged;
            protected void OnPropertyChanged(string propertyName)
            {
                if (this.PropertyChanged != null)
                {
                    this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
                }
            }

            #endregion
        }
        #endregion

        DataGrid m_Grid;
        public UserTaskPanel()
        {
            base.HorizontalContentAlignment = HorizontalAlignment.Stretch;
            base.VerticalContentAlignment = VerticalAlignment.Stretch;
            m_Grid = new DataGrid();
            
            m_Grid.Style = App.Current.Resources["DataGridGlowStyle"] as Style;
            m_Grid.RowStyle = App.Current.Resources["DataGridGlowRowStyle"] as Style;
            m_Grid.RowHeaderStyle = App.Current.Resources["DataGridGlowRowHeaderStyle"] as Style;
            m_Grid.CellStyle = App.Current.Resources["DataGridGlowCellStyle"] as Style;
            m_Grid.ColumnHeaderStyle = App.Current.Resources["DataGridColumnHeaderGlow"] as Style;
            m_Cache = new TaskCache(m_Grid);
            base.Content = m_Grid;

            m_Grid.AutoGenerateColumns = false;
            m_Grid.IsReadOnly = true;
            m_Grid.CanUserSortColumns = false;
            m_Grid.Columns.Add(new DataGridTemplateColumn() { CellTemplate = this.CreateImageTemplate(), Header = '#' });
            m_Grid.Columns.Add(new DataGridTextColumn() { Binding = new Binding("Caption"), Header = Localization.Str_Caption });
            m_Grid.Columns.Add(new DataGridTextColumn() { Binding = new Binding("FormId"), Header = Localization.Str_Form });
            m_Grid.Columns.Add(new DataGridTextColumn() { Binding = new Binding("Started"), Header = Localization.Str_Started });
            m_Grid.Columns.Add(new DataGridTextColumn() { Binding = new Binding("Finished"), Header = Localization.Str_Finished });
            m_Grid.Columns.Add(new DataGridTextColumn() { Binding = new Binding("Executed"), Header = Localization.Str_Executed });
            m_Grid.Columns.Add(new DataGridTextColumn() { Binding = new Binding("Description"), Header = Localization.Str_State, Width = DataGridLength.Auto });
            m_Grid.VerticalScrollBarVisibility = ScrollBarVisibility.Auto;
            m_Grid.HorizontalScrollBarVisibility = ScrollBarVisibility.Auto;

            CustomContextMenu menu = new CustomContextMenu();
            ContextMenuItem item = new ContextMenuItem(Localization.Str_CopyErrorDetails);
            item.ItemClick += new EventHandler(item_ItemClick);
            menu.AddMenuItem(item);
            this.AttachContextMenu(p =>
                {
                    TaskContainer container = m_Grid.SelectedItem as TaskContainer;
                    if (container != null && container.GetTask().Exception != null)
                    {
                        return menu;
                    }

                    return null;
                });
        }

        private DataTemplate CreateImageTemplate()
        {
            StringBuilder cellTemp = new StringBuilder();
            cellTemp.Append("<DataTemplate ");
            cellTemp.Append("xmlns='http://schemas.microsoft.com/client/2007' ");
            cellTemp.Append("xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>");

            cellTemp.Append("<Image Stretch='None' ");
            cellTemp.Append("Source='{Binding ");
            cellTemp.Append("StateImage");
            cellTemp.Append("}'></Image>");
            cellTemp.Append("</DataTemplate>");

            return (DataTemplate)XamlReader.Load(cellTemp.ToString());
        }

        void item_ItemClick(object sender, EventArgs e)
        {
            TaskContainer container = m_Grid.SelectedItem as TaskContainer;
            if (container != null && container.GetTask().Exception != null)
            {
                Clipboard.SetClipboardText(container.GetTask().Exception.ToString());
            }
        }

        private FrameworkElement CreateHeaderItem(string caption, int column)
        {
            Border border = new Border();
            border.BorderThickness = new Thickness(1.0);
            border.Background = new SolidColorBrush(Colors.LightGray);
            TextBlock txt = new TextBlock();
            txt.Text = caption;
            txt.FontWeight = FontWeights.Bold;
            txt.HorizontalAlignment = HorizontalAlignment.Stretch;
            txt.VerticalAlignment = VerticalAlignment.Stretch;
            txt.TextAlignment = TextAlignment.Center;
            border.Child = txt;

            Grid.SetRow(border, 0);
            Grid.SetColumn(border, column);

            return border;
        }

        private TaskCache m_Cache;
        public void AppendTask(UserTaskDescriptor task)
        {
            m_Cache.Append(task);
        }

        public void RefreshTasks()
        {
            m_Cache.RefreshAll();
        }

        public void ClearTasks()
        {
            m_Cache.ClearAll();
        }

        public void SetFilter(bool showAll)
        {
            m_Cache.SetFilter(showAll);
        }
    }
}
